package com.person.yhzs.util;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.util.TypeUtils;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;


/**
 * Json工具类
 *
 * @author Ry Huang
 * @date 2021-09-15
 */
public class JsonUtil {
    static final Logger LOGGER = LoggerFactory.getLogger(JsonUtil.class);

    static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    static {
        OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    private JsonUtil() {
    }

    /**
     * 反序列化单个对象
     *
     * @param jsonString Json字符串
     * @param clz        目标类.class
     * @param <T>        目标类
     * @return 目标类的对象
     */
    public static <T> T readValue(String jsonString, Class<T> clz) {
        try {
            return JSON.parseObject(jsonString, clz);
        } catch (Exception ignore) {
            LOGGER.info("从json获取对象失败， jsonString:{}, clz:{}, 原因：{}", jsonString, clz, ignore.getMessage());
        }
        return null;
    }

    /**
     * 从json字符串中获取指定key的值
     * @param jsonKey
     * @param jsonString
     * @return
     */
    public static Object readKeyValue(String jsonKey, String jsonString) {
        JSONObject jsonObject= (JSONObject) JSON.parse(jsonString);
        return jsonObject.get(jsonKey);
    }

    /**
     * 反序列化一组对象，以List返回
     */
    public static <T> List<T> readList(String jsonString, Class<T> clz) {
        try {
            return OBJECT_MAPPER.readValue(jsonString,
                    OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, clz));
        } catch (Exception ignore) {
            LOGGER.debug("从json获取list对象失败， jsonString:{}, clz:{}", jsonString, clz);
        }
        return null;
    }

    /**
     * 反序列化一组对象，以Set返回
     */
    public static <T> Set<T> readSet(String jsonString, Class<T> clz) {
        try {
            return OBJECT_MAPPER.readValue(jsonString,
                    OBJECT_MAPPER.getTypeFactory().constructCollectionType(Set.class, clz));
        } catch (Exception ignore) {
            LOGGER.debug("从json获取set对象失败，jsonString:{}, clz:{}", jsonString, clz);
        }
        return null;
    }

    /**
     * 反序列化一组对象，以Map返回
     */
    public static Map<String, Object> readMap(String jsonString) {
        try {
            return OBJECT_MAPPER.readValue(jsonString,
                    OBJECT_MAPPER.getTypeFactory().constructMapType(HashMap.class, String.class, Object.class));
        } catch (Exception ignore) {
            LOGGER.debug("从json获取Map对象失败，jsonString:{}", jsonString);
        }
        return null;
    }

    /**
     * @param value 序列化的对象
     * @return Json字符串
     */
    public static String writeValueAsString(Object value) {
        try {
            return OBJECT_MAPPER.writeValueAsString(value);
        } catch (Exception ignore) {
            LOGGER.debug("对象反序列化为String失败, clz:{}", value);
        }
        return null;
    }

    /**
     * @param value 序列化的对象
     * @return Json字符串
     */
    public static byte[] writeValueAsBytes(Object value) {
        try {
            return OBJECT_MAPPER.writeValueAsBytes(value);
        } catch (Exception ignore) {
            LOGGER.debug("对象反序列化为byte[]失败, clz:{}", value);
        }
        return null;
    }

    /**
     * 将对象的集合转为指定类型对象的List输出。
     *
     * @param value
     * @param target
     * @param <T>
     * @return
     */
    public static <T> List<T> convertValueList(Object value, Class<T> target) {
        try {
            if (value instanceof Collection) {
                Collection collection = (Collection) value;
                List list = new ArrayList(collection.size());
                collection.forEach(item ->{
                    list.add(convertValue(item, target));
                });
                return list;
            } else {
                List list = new ArrayList(1);
                list.add(convertValue(value, target));
                return list;
            }
//            return OBJECT_MAPPER.convertValue(value,
//                    OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, target));
        } catch (Exception ignore) {
            LOGGER.info("将对象{}的集合转为{}的List集合失败,原因:{}", value, target, ignore.getMessage());
        }
        return null;
    }

    /**
     * 将指定对象转为指定类型对象的输出。
     *
     * @param value
     * @param target
     * @param <T>
     * @return
     */
    public static <T> T convertValue(Object value, Class<T> target) {
        try {
            if (value instanceof Map) {
                return TypeUtils.castToJavaBean(value, target);
            } else {
                return readValue(writeValueAsString(value), target);
            }
        } catch (Exception ignore) {
            LOGGER.info("对象{}转为{}失败, 原因：{}", value, target, ignore.getMessage());
        }
        return null;
    }
}
